const axios = require('axios')
const crypto = require('crypto')
const fs = require('node:fs') // node内置模块，用于文件系统操作。

const wxConfig = {
  appid: 'wx42ad5abf8d45edcc',
  secret: '2fca387f4108a082c204f443bcaea880',
  mchid: '1699691184',
  serial_no: '44D7ECBAF4398818BAA5E397C57A8E1508D79FD7',
  apiV3Key: 'wusaisai20190808baicuiting940606',
  notifyUrl: 'https://www.tjhuabo.com.cn/api/v1/wechat/notify',
}
const wechatAuthCode = async (code) => {
  const url = `https://api.weixin.qq.com/sns/jscode2session`
  const response = await axios({
    method: 'GET',
    url,
    params: {
      appid: wxConfig.appid,
      secret: wxConfig.secret,
      js_code: code,
      grant_type: 'authorization_code',
    },
  })
  return response
}

const wechatPay = async (request, reply) => {
  const { code } = request.body
  const result = await wechatAuthCode(code)
  return reply.code(200).send({
    message: '获取openid成功',
    data: result.data,
    error: null,
    code: reply.statusCode,
  })
}

// 生成随机字符串
function generateNonceStr(len) {
  let data = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'
  let str = ''
  for (let i = 0; i < len; i++) {
    str += data.charAt(Math.floor(Math.random() * data.length))
  }
  return str
}

/**
 * 微信支付v3 下单签名值生成
 * @param {string} pem pem证书名称
 * @param {string} method 请求方法
 * @param {string} url  微信小程序下单官方api
 * @param {number} timestamp 时间戳 秒级
 * @param {string} nonce_str 随机字符串
 * @param {Object} order 主体（订单）信息
 */
function createOrderSign(method, url, timestamp, nonce_str, order) {
  // 签名串
  let signStr = `${method}\n${url}\n${timestamp}\n${nonce_str}\n${JSON.stringify(order)}\n`
  // 读取API证书文件内容 apiclient_key.pem的内容
  let cert = fs.readFileSync(`/dyxw/ssl/apiclient_key.pem`, 'utf8')
  // 创建使用 RSA 算法和 SHA-256 散列算法的签名对象
  let sign = crypto.createSign('RSA-SHA256')
  // 对签名串进行加密处理
  sign.update(signStr)
  return sign.sign(cert, 'base64')
}

// 预支付 签名
const createPaySign = async function (prepay_id) {
  let timeStamp = Math.floor(new Date().getTime() / 1000).toString()
  let nonceStr = generateNonceStr(32)

  let signStr = `${wxConfig.appid}\n${timeStamp}\n${nonceStr}\nprepay_id=${prepay_id}\n`
  let cert = fs.readFileSync(`/dyxw/ssl/apiclient_key.pem`, 'utf8')
  let sign = crypto.createSign('RSA-SHA256')
  sign.update(signStr)
  return {
    paySign: sign.sign(cert, 'base64'),
    timestamp: timeStamp,
    nonce_str: nonceStr,
    signType: 'RSA',
    package: 'prepay_id=' + prepay_id,
  }
}

// 请求签名值
const fetchPrepayId = async (wxOrder) => {
  let timestamp = Math.floor(new Date().getTime() / 1000)
  let nonce_str = generateNonceStr(32)

  let signature = createOrderSign(
    'POST',
    '/v3/pay/transactions/jsapi',
    timestamp,
    nonce_str,
    wxOrder
  )
  let Authorization = `WECHATPAY2-SHA256-RSA2048 mchid="${wxConfig.mchid}",nonce_str="${nonce_str}",timestamp="${timestamp}",signature="${signature}",serial_no="${wxConfig.serial_no}"`
  const { data } = await axios.post(
    'https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi',
    wxOrder,
    {
      headers: {
        Authorization: Authorization,
        'Content-Type': 'application/json',
        Accept: 'application/json',
      },
    }
  )
  const result = await createPaySign(data.prepay_id)
  return result
}

const wechatPreOrder = async (request, reply) => {
  const { openId, orderTotal, orderNo, productName, productPrice } =
    request.body
  let wxOrder = {
    mchid: wxConfig.mchid,
    appid: wxConfig.appid,
    notify_url: wxConfig.notifyUrl, // 回调地址 这里需要我们自行实现用来接收支付结果信息
    out_trade_no: orderNo, // 上面创建的订单的订单号 我们自己自定义的 28
    description: productName, // 商品描述
    amount: {
      total: productPrice, // 单位为分
      currency: 'CNY',
    },
    payer: {
      openid: openId,
    },
  }
  const result = await fetchPrepayId(wxOrder)
  return reply.code(200).send({
    message: '唤起支付成功',
    data: result,
    code: result.statusCode,
    error: null,
  })
}
const wechatNotify = async (request, reply) => {
  console.log(request)
  return
}
module.exports = {
  wechatPay,
  wechatPreOrder,
  wechatNotify,
}
